home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 15043 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  4.5 KB

  1. Path: news.ucdavis.edu!quad!knight
  2. From: knight@quad.cs.ucdavis.edu (James Knight)
  3. Newsgroups: comp.lang.c,comp.unix.programmer
  4. Subject: Re: Q: '\n' character
  5. Followup-To: comp.lang.c,comp.unix.programmer
  6. Date: 16 Apr 1996 21:37:34 GMT
  7. Organization: University of California, Davis
  8. Message-ID: <4l13uu$mva@mark.ucdavis.edu>
  9. References: <4kj66f$k0o@ren.cei.net> <AD97189A966891F2@mcdiala02.it.luc.edu> <4ktn04INNoev@keats.ugrad.cs.ubc.ca> <4ku8f9$d3o@mark.ucdavis.edu> <4kumbqINNgcr@mayne.ugrad.cs.ubc.ca>
  10. NNTP-Posting-Host: quad.cs.ucdavis.edu
  11. X-Newsreader: TIN [version 1.2 PL2]
  12.  
  13. Kazimir Kylheku (c2a192@ugrad.cs.ubc.ca) wrote:
  14. : In article <4ku8f9$d3o@mark.ucdavis.edu>,
  15. : James Knight <knight@quad.cs.ucdavis.edu> wrote:
  16.  
  17. : This is a good effort: I will try to look for any marginal improvements.
  18.  
  19. :  >    if ((buffer = realloc(buffer, bufsize)) == NULL)
  20. :  >      return NULL;
  21.  
  22. : Just one quip: when realloc() fails, the original data is not lost. So you have
  23. : to keep the original pointer around, and be ready to either leave the data as
  24. : it is, or free() it.
  25.  
  26. It depends on which realloc is used.  The man page for the default realloc on my
  27. system (Ultrix 4.3A) says that the block may be destroyed.  And, I'll admit that
  28. the one major deficiency of this procedure is that it does not distinguish
  29. between EOF, Read Errors and Malloc/Realloc errors.  I didn't do that, because
  30. the error handling really depends on how the rest of the program wants to
  31. handle errors.  Should it use a local "errno" value to signal an error, should
  32. it just print an error message and exit, or should it do something else?  Once
  33. the error handling of the program is determined, then the error handling of
  34. the function can be set.
  35.  
  36. If you needed a truly robust version and the rest of the program was both
  37. aware of the memory error and was able to free up memory, then you could add
  38. a static memory interrupt flag to the function that was set when the memory
  39. error occurs and when the function is called after it was set, skips the
  40. initial allocation and read and moves the computation into the while loop
  41. again.  There's no point in the function trying to free anything from inside
  42. the function, because all of the memory is needed to retain the portion of
  43. the current line.
  44.  
  45.  
  46. :  >  /*
  47. :  >   * Strip the newline from the line, if it's there.
  48. :  >   */
  49. :  >  if (buffer[len-1] == '\n')
  50. :  >    buffer[--len] = '\0';
  51. :  >
  52. :  >  if (len_out) *len_out = len;
  53. :  >  return buffer;
  54.  
  55. : Ah, you forgot to adjust the buffer size for the actual length read! If the
  56. : line is 128K plus one byte, you will return 256K---the next higher power of
  57. : two. No biggie, but it's easy to fix with a realloc down to the actual size.
  58. : I'm not sure how paranoid one ought to be when checking the result of a
  59. : _shrinking_ realloc, but I'd treat it the same was as a growing one to be safe.
  60.  
  61. Except for one point, does it really matter whether the allocated array is longer
  62. than the line?  The rest of the program should never touch the memory after the
  63. array (or free/realloc the array), so it shouldn't matter to the program how long
  64. the array is.  The only exception is that if a really long line is read, and then
  65. shorter lines are read, then the function should probably shorten its length to
  66. free up as much space as possible.  But, on machines today, this only becomes
  67. a problem when you get near the MB range, and for the purpose I was using it for
  68. (namely, reading typed in lines and files where a limited line length was assumed)
  69. it was never that big a problem.
  70.  
  71.  
  72. : Nevertheless, my original comments about fgets() versus loops that use getc()
  73. : apply: the above might be quite a bit cleaner if you were content to spoon out
  74. : a character at a time. No strlen(), no odd buffer manipulation---just a pointer
  75. : that you advance, and check against the buffer bounds.
  76.  
  77. Yes, but which one is faster.  I did this experiment for a class I was teaching,
  78. where I compared all combinations of fgetc, fgets, fputc and fputs for a cat
  79. program that does line by line reading. The fgetc/fputc combination ran in 
  80. about 10 seconds (I think I was reading 1MB of text), the fgets/fputc and
  81. fgetc/fputs combinations ran in about 6.5-7 seconds and the fgets/fputs
  82. combination ran in 3.5 seconds.  I can post more details about this, if you
  83. like.
  84.  
  85.  
  86. : What about dealing with null characters in the input lines?
  87.  
  88. I didn't worry about those.  I've never seen a text file that had null
  89. characters, and most of the text writing programs (text editors and the basic
  90. Unix utilities) won't insert any null characters into files.  So, I didn't
  91. worry about it.
  92.  
  93. Jim
  94.  
  95.